# -*- coding: utf-8 -*-
import re
from django.views.generic.simple import direct_to_template
from django.http import HttpResponseRedirect
from lr.register.models import Profile, Invite
from lr.settings import MEDIA_URL
from django.utils.safestring import mark_safe
from lr.cabinet.forms import CabinetPerson1, CabinetPerson2, InviteForm
from lr.message.models import LrMessage
from django.template.loader import render_to_string
from lr.bank.models import Bank, Transaction
from django.db.models import Q
from lr.work.models import Work
from lr.face.views import check_user
from django.shortcuts import render_to_response
from django.contrib.auth.models import User
from lr.cabinet.models import ViewOptions, UserRels


def cabinet(request):
    """ Обработчик запросов к кабинету """
    if not check_user(request):
        return render_to_response('lock_account.html')
    
    if 'view' in request.GET:
        user_id = request.GET['view']
        return view_user(request, user_id)
    
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/')
    
    if 'select' in request.GET:
        select = request.GET['select']
        if select == 'profile':
            return cabinet_profile(request)
        elif select == 'bank':
            return cabinet_bank(request)
        elif select == 'invites':
            return cabinet_invites(request)
    elif 'edit' in request.GET:
        edit = request.GET['edit']
        if edit == 'person':
            return cabinet_person(request)
        elif edit == 'birthday':
            return cabinet_birthday(request)
        elif edit == 'email':
            return cabinet_email(request)
        elif edit == 'avatar':
            return cabinet_avatar(request)
    elif 'bank' in request.GET:
        bank = request.GET['bank']
        if bank == 'recharge':
            return bank_recharge(request)
        elif bank == 'cash':
            return bank_cash(request)
    
    return cabinet_main(request)


def cabinet_main(request):
    """ Заглавная страница кабинета """
    works = Work.objects.filter(author=request.user)
    cab_data = _prepare_cab_data(request.user, request.profile)
    cab_data['writings'] = works.filter(fosterling=None)
    cab_data['reviews'] = works.exclude(fosterling=None)
    return direct_to_template(request, 'cabinet/cabinet.html', cab_data)


def cabinet_profile(request):
    """ Страница профайла пользователя """
    cab_data = _prepare_cab_data(request.user, request.profile)
    if not cab_data['is_writer']:
        if request.method == 'POST':
            invite_form = InviteForm(request.POST)
            if invite_form.is_valid():
                # Пользователь активировал приглашение
                keys = re.search(ur'^(?P<k0>[0-9\u0041-\u0046]{4})\-(?P<k1>[0-9\u0041-\u0046]{4})\-(?P<k2>[0-9\u0041-\u0046]{4})\-(?P<k3>[0-9\u0041-\u0046]{4})$',
                                 request.POST['invite'])
                if keys:
                    k0 = int('0x' + keys.group('k0'), 16)
                    k1 = int('0x' + keys.group('k1'), 16)
                    k2 = int('0x' + keys.group('k2'), 16)
                    k3 = int('0x' + keys.group('k3'), 16)
                    
                    try:
                        invite = Invite.objects.get(key0=k0, key1=k1, key2=k2, key3=k3)
                        if not request.profile.is_empty():
                            invite.delete()
                            if not request.profile.is_writer():
                                request.profile.rank = 1
                                request.profile.save()
                            name, gender = Profile.get_user_name(user=request.user, profile=request.profile)
                            LrMessage.objects.create_message(user=request.user, title=u'Получен %d ранг' % request.profile.rank,
                                                             description=render_to_string('messages/new_rank.html',
                                                                              { 'gender': gender, 'name': name }))
                            return HttpResponseRedirect('message')
                    except:
                        pass
        else:
            invite_form = InviteForm()
        cab_data['invite_form'] = invite_form
    return direct_to_template(request, 'cabinet/cabinet_profile.html', cab_data)


def cabinet_bank(request):
    """ Страница банка """
    bank = Bank.objects.get(user=request.user)
    transactions = Transaction.objects.filter(Q(sender=request.user) | Q(recipient=request.user)).order_by('-time')[:50]
    book = []
    for transaction in transactions:
        if transaction.sender == request.user:
            book.append({ 'time': transaction.time, 'detail': transaction.detail, 'cash': '-%.2f' % transaction.cash })
        else:
            book.append({ 'time': transaction.time, 'detail': transaction.detail, 'cash': '+%.2f' % transaction.cash })
    cab_data = {}
    cab_data['cash'] = '%.2f' % bank.cash
    cab_data['book'] = book
    return direct_to_template(request, 'cabinet/cabinet_bank.html', cab_data)


def bank_recharge(request):
    """ Пополнить счет """
    donate = 100
    Transaction.objects.create_transaction(cash=donate, detail=u'Счет пополнен', recipient=request.user)
    LrMessage.objects.create_message(request.user, u'Счет пополнен',
                                     render_to_string('messages/recharge_complete.html', { 'cash': donate }))
    return HttpResponseRedirect('message')


def bank_cash(request):
    """ Вывести наличные из системы """
    return direct_to_template(request, 'cabinet/cabinet_cash.html')


def _prepare_cab_data(user, profile):
    """ Вспомогательная функция подготовки данных для заглавных страниц кабинете """
    cab_data = {}
    cab_data['is_writer'] = profile.is_writer()
    cab_data['name'] = user.username
    cab_data['first_name'] = user.first_name
    cab_data['last_name'] = user.last_name
    cab_data['email'] = user.email
    
    if profile:
        cab_data['patronymic'] = profile.patronymic
        cab_data['nickname'] = profile.nickname
        cab_data['birthday'] = profile.birthday
        cab_data['userpic'] = profile.userpic
        cab_data['about'] = profile.about
        cab_data['presentation'] = Profile.make_sign(cab_data, profile.presentation)
        cab_data['sign'] = Profile.make_sign(cab_data, profile.sign)
    
    if not 'userpic' in cab_data \
    or not cab_data['userpic'] \
    or not cab_data['userpic'].url:
        cab_data['userpic'] = MEDIA_URL + 'default_userpic.jpg'
    
    return cab_data



def cabinet_invites(request):
    """ Страница приглашений """
    if request.method == 'POST':
        if 'make_invite' in request.POST \
        and request.user.is_superuser:
            # Запрос на создание нового приглашения
            Invite.objects.create_invite(owner=request.user)
    
    invites = Invite.objects.filter(owner=request.user)
    inv_list = []
    for invite in invites:
        inv_list.append(u'%.4X-%.4X-%.4X-%.4X' % (invite.key0, invite.key1, invite.key2, invite.key3))
    cab_data = {}
    cab_data['is_superuser'] = request.user.is_superuser
    if len(inv_list) > 0:
        cab_data['invites'] = inv_list
    return direct_to_template(request, 'cabinet/cabinet_invites.html', cab_data)



def view_user(request, user_key):
    """ Показать карточку пользователя по его id или нику """
    try:
        user_id = int(user_key)
        user_name = ''
    except:
        user_id = 0
        user_name = user_key
    
    has_rels = request.user.is_authenticated() and request.user.is_active
    if has_rels:
        self_view = request.user.id == user_id or request.user.username == user_name
    else:
        self_view = False
    
    if self_view:
        # Запрос собственной карточки
        return cabinet_main(request)
    
    try:
        user = User.objects.get(Q(id=user_id) | Q(username=user_name))
        profile = Profile.objects.get(user=user)
        view_opt = ViewOptions.objects.get(user=user)
    except:
        return HttpResponseRedirect('/')
    
    if has_rels:
        is_friend = len(UserRels.objects.filter(user=request.user, friends__id=user.id)) > 0
        is_ignored = len(UserRels.objects.filter(user=request.user, ignored__id=user.id)) > 0
        is_banned = len(UserRels.objects.filter(user=request.user, banned__id=user.id)) > 0
        
        im_his_friend = len(UserRels.objects.filter(user=user, friends__id=request.user.id)) > 0
        ignored_me = len(UserRels.objects.filter(user=user, ignored__id=request.user.id)) > 0
        ban_me = len(UserRels.objects.filter(user=user, banned__id=request.user.id)) > 0
        
        if request.method == 'POST':
            # Пришел запрос на изменение статуса для этого пользователя
            rels = UserRels.objects.get(user=request.user)
            if 'add_friend' in request.POST \
            and not is_friend:
                # Добавить этого пользователя в друзья
                rels.friends.add(user)
                is_friend = True
                if is_ignored:
                    rels.ignored.remove(user)
                    is_ignored = False
                if is_banned:
                    rels.banned.remove(user)
                    is_banned = False
            elif 'add_ignore' in request.POST \
            and not is_ignored:
                # Добавить этого пользователя в игнор-лист
                if is_friend:
                    rels.friends.remove(user)
                    is_friend = False
                rels.ignored.add(user)
                is_ignored = True
                if is_banned:
                    rels.banned.remove(user)
                    is_banned = False
            elif 'add_ban' in request.POST \
            and not is_banned:
                # Забанить этого пользователя
                if is_friend:
                    rels.friends.remove(user)
                    is_friend = False
                if is_ignored:
                    rels.ignored.remove(user)
                    is_ignored = False
                rels.banned.add(user)
                is_banned = True
            elif 'remove_friend' in request.POST and is_friend:
                # Удалить пользователя из списка друзей
                rels.friends.remove(user)
                is_friend = False
            elif 'remove_ignore' in request.POST and is_ignored:
                # Удалить пользователя из списка игнорируемых
                rels.ignored.remove(user)
                is_ignored = False
            elif 'remove_ban' in request.POST and is_banned:
                # Разбанить пользователя
                rels.banned.remove(user)
                is_banned = False
            elif 'deal' in request.POST and request.user.is_authenticated() \
            and profile.is_jour() and not ignored_me and not ban_me:
                # Оформить заказ у этого писателя
                return make_deal(request=request, writer=user)
    else:
        is_friend = False
        is_ignored = False
        is_banned = False
        im_his_friend = False
        ignored_me = False
        ban_me = False
    
    cab_data = {}
    cab_data['is_writer'] = request.profile.is_writer()
    cab_data['is_jour'] = profile.is_jour()
    cab_data['has_rels'] = has_rels
    cab_data['is_friend'] = is_friend
    cab_data['is_ignored'] = is_ignored
    cab_data['is_banned'] = is_banned
    cab_data['im_his_friend'] = im_his_friend
    cab_data['ignored_me'] = ignored_me
    cab_data['ban_me'] = ban_me
    cab_data['presentation'] = Profile.get_user_name(user=user, profile=profile)[0]
    
    if not profile.userpic or not profile.userpic.url:
        cab_data['userpic'] = MEDIA_URL + 'default_userpic.jpg'
    
    if view_opt.show_username == u'all' \
    or has_rels and view_opt.show_username == u'user' \
    or im_his_friend and view_opt.show_username == u'friend':
        cab_data['name'] = user.username
    
    if view_opt.show_birthday == u'all' \
    or has_rels and view_opt.show_birthday == u'user' \
    or im_his_friend and view_opt.show_birthday == u'friend':
        cab_data['birthday'] = profile.birthday
    
    if view_opt.show_email == u'all' \
    or has_rels and view_opt.show_email == u'user' \
    or im_his_friend and view_opt.show_email == u'friend':
        cab_data['email'] = user.email
    
    if view_opt.show_about == u'all' \
    or has_rels and view_opt.show_about == u'user' \
    or im_his_friend and view_opt.show_about == u'friend':
        cab_data['about'] = profile.about
    
    if view_opt.show_works == u'all' \
    or has_rels and view_opt.show_works == u'user' \
    or im_his_friend and view_opt.show_works == u'friend':
        works = Work.objects.filter(author=user)
        cab_data['writings'] = works.filter(fosterling=None)
        cab_data['reviews'] = works.exclude(fosterling=None)
    
    return direct_to_template(request, 'cabinet/cabinet_view.html', cab_data)


def make_deal(request, writer):
    """ Оформить персональный заказ на писателя """
    request.session['contest_person'] = writer
    return HttpResponseRedirect('board?action=new')


def cabinet_person(request):
    """ Страница смены представления персоны пользователя """
    cab_data = {}
    
    if request.method == 'POST':
        cabinet_person1 = CabinetPerson1(request.POST)
        cabinet_person2 = CabinetPerson2(request.POST)
        
        if cabinet_person1.is_valid() and cabinet_person2.is_valid():
            try:
                profile = cabinet_person1.save(user=request.user, last_name=request.POST['last_name'],
                                               first_name=request.POST['first_name'], patronymic=request.POST['patronymic'],
                                               nickname=request.POST['nickname'],
                                               profile=cabinet_person2.save(user=request.user,
                                                                            presentation=request.POST['presentation'],
                                                                            sign=request.POST['sign'],
                                                                            gender=request.POST['gender'],
                                                                            profile=request.profile, update_now=False),
                                               update_now=False)
            except:
                # Профиль пользователя поврежден, или не может быть найден,
                # выдать соответствующее сообщение пользователю
                LrMessage.objects.create_message(request.user, u'Профиль поврежден',
                                                 render_to_string('messages/profile_corrupted_message.html',
                                                                  { 'name': request.user.username }))
                return HttpResponseRedirect('message')
            
            if 'about' in request.POST:
                profile.about = request.POST['about']
            profile.save()
            
            request.user.first_name = request.POST['first_name']
            request.user.last_name = request.POST['last_name']
            request.user.save()
            
            return HttpResponseRedirect('cabinet?select=profile')
        else:
            cab_data['gender_list'] = _make_gender_list(request.POST['gender'])
            cab_data['about'] = request.POST['about']
    else:
        forms_data = {}
        
        forms_data['first_name'] = request.user.first_name
        forms_data['last_name'] = request.user.last_name
        
        try:
            forms_data['patronymic'] = request.profile.patronymic
            forms_data['nickname'] = request.profile.nickname
            forms_data['gender'] = request.profile.gender
            forms_data['presentation'] = request.profile.presentation
            forms_data['sign'] = request.profile.sign
            
            cab_data['about'] = request.profile.about
        except:
            pass
        
        cabinet_person1 = CabinetPerson1(forms_data)
        cabinet_person2 = CabinetPerson2(forms_data)
        
        cab_data['gender_list'] = _make_gender_list(forms_data.get('gender', u'x'))
    
    cab_data['person_data1'] = cabinet_person1
    cab_data['person_data2'] = cabinet_person2
    cab_data['is_writer'] = request.profile.is_writer()
    
    return direct_to_template(request, 'cabinet/cabinet_person.html', cab_data)


def _make_gender_list(gender):
    """ Вспомогательная функция, формирует список для выбора пола """
    gender_list = []
    for key, value in Profile.GENDER_CHOICES:
        gender_item = u'<li><input type="radio" name="gender" value="' + key + '"';
        if key == gender:
            gender_item += u' checked'
        gender_item += u'/> ' + value + u'</li>'
        gender_list.append(gender_item)
    return mark_safe(u'\n'.join(gender_list))


def cabinet_birthday(request):
    """ Страница изменения дня рождения и настроек его отображения """
    cab_data = {}
    
    if request.method == 'POST':
        pass
    else:
        pass
    return direct_to_template(request, 'cabinet/cabinet_birthday.html', cab_data)


def cabinet_email(request):
    """ Страница изменения e-mail-а и настроек его отображения """
    cab_data = {}
    
    if request.method == 'POST':
        pass
    else:
        pass
    return direct_to_template(request, 'cabinet/cabinet_email.html', cab_data)


def cabinet_avatar(request):
    """ Страница изменения аватара """
    cab_data = {}
    
    if request.method == 'POST':
        pass
    else:
        pass
    return direct_to_template(request, 'cabinet/cabinet_avatar.html', cab_data)
